#ifndef EXPSAMPLE_H
#define EXPSAMPLE_H

#include "analytedatabase.h"

struct ExpResult//待定
{
    ExpResult()
    {
        cnCal=0;
        cpsCal=0;
        cpsJamming=0;
        isotope=0;
        cnHalf=0;
    }
    friend QDataStream & operator<< ( QDataStream & stream, const ExpResult & expResult )
    {
        stream<<expResult.cnCal
                <<expResult.cpsCal
                <<expResult.cpsJamming
                <<expResult.isotope
                <<expResult.cnHalf;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, ExpResult & expResult )
    {
        stream>>expResult.cnCal
                >>expResult.cpsCal
                >>expResult.cpsJamming
                >>expResult.isotope
                >>expResult.cnHalf;
        return stream;
    }

    //QList<double> datas;//原始数据

    //结果表 每个结果单独计算
    double cnCal;
    double cpsCal;
    double cpsJamming;

    double isotope;
    double cnHalf;//
    //
};

struct SampleScanPara
{
    SampleScanPara()
    {
        state=false;
        bIsShow=false;
        color=QColor(Qt::blue);
    }
    friend QDataStream & operator<< ( QDataStream & stream, const SampleScanPara & para )
    {
        stream<<para.state;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, SampleScanPara & para )
    {
        stream>>para.state;
        return stream;
    }

    int state;
    bool bIsShow;//
    QColor color;//
};
struct PreScanResult
{
    void SetPreScanState(int state)
    {
        scanState.state=state;
    }
    int GetPreScanState()
    {
        return scanState.state;
    }

    void SetPreExpRawData(QList<ExpRawData> datas)
    {
        expRawDatas=datas;
    }
    QList<ExpRawData> GetPreExpRawData()
    {
        return expRawDatas;
    }

    QHash<QString,double> GetCnHalfs();
    void SetCnHalfs(QHash<QString,double>);

    friend QDataStream & operator<< ( QDataStream & stream, const PreScanResult & para )
    {
        stream<<para.scanState
              <<para.expRawDatas;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, PreScanResult & para )
    {
        stream>>para.scanState
              >>para.expRawDatas;
        return stream;
    }
    //次数 段或元素 相关
    SampleScanPara scanState;//
    QList<ExpRawData> expRawDatas;//QList<ExpRawData>：通道相关

    //结果
    QList<ExpRawData> expDatas;//cal
    QHash<QString,double> cnHalfs;//
};
struct MainScanResult
{
    void SetMainScanState(int state)
    {
        scanState.state=state;
    }
    int GetMainScanState()
    {
        return scanState.state;
    }

    void SetMainExpRawData(QList<ExpRawData> datas)
    {
        expRawDatas=datas;
    }
    QList<ExpRawData> GetMainExpRawData()
    {
        return expRawDatas;
    }

    QHash<QString,double> GetCnCals();
    QHash<QString,double> GetCpsCals();
    QHash<QString,double> GetCpsJammings();
    QHash<QString,double> GetCpsInternals();
    QHash<QString,double> GetIsotopes();
    QList<double> GetRatios();

    void SetCnCals(QHash<QString,double>);
    void SetCpsCals(QHash<QString,double>);
    void SetCpsJammings(QHash<QString,double>);
    void SetCpsInternals(QHash<QString,double>);
    void SetIsotopes(QHash<QString,double>);
    void SetRatios(QList<double>);

    double GetInternalCps(double x);

    friend QDataStream & operator<< ( QDataStream & stream, const MainScanResult & para )
    {
        stream<<para.scanState
              <<para.expRawDatas;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, MainScanResult & para )
    {
        stream>>para.scanState
              >>para.expRawDatas;
        return stream;
    }
    //次数 段或元素 相关
    SampleScanPara scanState;
    QList<ExpRawData> expRawDatas;//

    //结果
    QList<ExpRawData> expDatas;//cal:交叉校正
    QHash<QString,double> cnCals;//浓度
    QHash<QString,double> cpsCals;//扫描元素
    QHash<QString,double> cpsJammings;//去背景(cpsCals)
    QHash<QString,double> isotopes;//元素比(cpsCals)
    QHash<QString,double> cpsInternals;//去内标(cpsJammings)
    QList<double> ratios;//
};
struct SampleInfor
{
    SampleInfor()
    {
        sampleName="Sample0";//
        sampleType="未知样品";//
        qcType="无";//
        restartSample="无";//
        relateSample="无";//
        preScanCount=0;///
        mainScanCount=3;
        dilutionFactor=1;
        internalS="[]";
        specialBlank="无";
        bShowReport=true;
        samplePositon="A111";
        //bIsFinish=false;//
        scanState=0;

        SetPreScanCount(preScanCount);
        SetMainScanCount(mainScanCount);
    }

    void SetPreScanCount(int count)
    {
        preScanCount=count;
        preScanResults.clear();
        for(int i=0;i<preScanCount;i++)
        {
          PreScanResult preScanResult;
          preScanResults.append(preScanResult);
        }
    }
    void SetMainScanCount(int count)
    {
        mainScanCount=count;
        mainScanResults.clear();
        for(int i=0;i<mainScanCount;i++)
        {
            MainScanResult mainScanResult;
            mainScanResults.append(mainScanResult);
        }
    }
    PreScanResult* GetPreScanResultPtr(int index)
    {
        return &preScanResults[index];
    }
    MainScanResult* GetMainScanResultPtr(int index)
    {
        return &mainScanResults[index];
    }

    QHash<QString,double> GetRsdCnCals()
    {
         return rsdCnCals;
    }
    QHash<QString,double> GetRsdCpsCals()
    {
       return rsdCpsCals;
    }
    QHash<QString,double> GetRsdCpsJammings()
    {
       return rsdCpsJammings;
    }
    QHash<QString,double> GetRsdIsotopes()
    {
       return rsdIsotopes;
    }

    QHash<QString,double> GetCnInputs()
    {
       return cnInputs;
    }
    QHash<QString,double> GetCnInputStandards()
    {
       return cnInputStandards;
    }

    void SetRsdCnCals(QHash<QString,double> datas)
    {
        rsdCnCals=datas;
    }
    void SetRsdCpsCals(QHash<QString,double> datas)
    {
        rsdCpsCals=datas;
    }
    void SetRsdCpsJammings(QHash<QString,double> datas)
    {
        rsdCpsJammings=datas;
    }
    void SetRsdIsotopes(QHash<QString,double> datas)
    {
       rsdIsotopes=datas;
    }

    void SetCnInputs(QHash<QString,double> datas)
    {
        cnInputs=datas;
    }
    void SetCnInputStandards(QHash<QString,double> datas)
    {
        cnInputStandards=datas;
    }

    friend QDataStream & operator<< ( QDataStream & stream, const SampleInfor & sampleInfor )
    {
        stream<<sampleInfor.sampleName
                <<sampleInfor.sampleType
                <<sampleInfor.qcType
                <<sampleInfor.restartSample
                <<sampleInfor.relateSample
                <<sampleInfor.preScanCount
                <<sampleInfor.mainScanCount
                <<sampleInfor.dilutionFactor
                <<sampleInfor.internalS
                <<sampleInfor.specialBlank
                <<sampleInfor.bShowReport
                <<sampleInfor.samplePositon
                <<sampleInfor.cnInputs
                <<sampleInfor.cnInputStandards
                <<sampleInfor.scanState
                <<sampleInfor.preScanResults
                <<sampleInfor.mainScanResults;

        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, SampleInfor & sampleInfor )
    {
        stream>>sampleInfor.sampleName
                >>sampleInfor.sampleType
                >>sampleInfor.qcType
                >>sampleInfor.restartSample
                >>sampleInfor.relateSample
                >>sampleInfor.preScanCount
                >>sampleInfor.mainScanCount
                >>sampleInfor.dilutionFactor
                >>sampleInfor.internalS
                >>sampleInfor.specialBlank
                >>sampleInfor.bShowReport
                >>sampleInfor.samplePositon
                >>sampleInfor.cnInputs
                >>sampleInfor.cnInputStandards
                >>sampleInfor.scanState               
                >>sampleInfor.preScanResults
                >>sampleInfor.mainScanResults;

        return stream;
    }

    QString sampleName;//
    QString sampleType;//
    QString qcType;//
    QString restartSample;//
    QString relateSample;//
    int preScanCount;///
    int mainScanCount;//
    double dilutionFactor;
    QString internalS;
    QString specialBlank;
    bool bShowReport;
    QString samplePositon;
    //bool bIsFinish;//scanState
    int  scanState;//sample 0:未扫描 1：扫描中 2：扫描完成

    //输入
    QHash<QString,double> cnInputs;//输入浓度
    QHash<QString,double> cnInputStandards;

    //次数 段或元素 相关
    QList<PreScanResult> preScanResults;
    QList<MainScanResult> mainScanResults;

    //结果
    QHash<QString,double> rsdCnCals;//元素相关 rsd
    QHash<QString,double> rsdCpsCals;
    QHash<QString,double> rsdCpsJammings;
    QHash<QString,double> rsdIsotopes;
};

struct CalRatioPara
{
    //校准曲线:全定量、标准加入（Method 相关）
    QList<double> ratios;//一次、二次函数（a、b、c）
    double rr;
    //一个浓度、一组cps（校准，扣干扰）
};

class Experiment ;
class ExpSample
{
public:
    ExpSample();

    QList<SampleInfor> GetSampleInfors();
    SampleInfor GetSampleInfor(int index);
    bool SetSampleInfor(int index,SampleInfor infor);
    QList<SampleInfor>* GetSampleInforsPtr();
    SampleInfor* GetSampleInforPtr(int index);
    void SetExpPtr(Experiment*);
    int GetSampleCount();
    //计算
    void CalRatioss();
    bool GetBlank(SampleInfor &sampleInfor);

    friend QDataStream & operator<< ( QDataStream & stream,  const ExpSample & expSample )
    {
        stream<<expSample.sampleInfors;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, ExpSample & expSample )
    {
        stream>>expSample.sampleInfors;
        return stream;
    }

    QList<SampleInfor> sampleInfors;

    Experiment *pExperiment;
    QHash<QString,CalRatioPara> calRatios;
    //0标准
    //空白
    //
};

#endif // EXPSAMPLE_H
